<?php

declare(strict_types=1);

namespace App\CustHub\Service;

use App\CustHub\Mapper\ChContactBwDeleteRecordMapper;
use App\CustHub\Mapper\ChContactWhiteMapper;
use App\CustHub\Model\ChContact;
use App\CustHub\Model\ChContactWhite;
use App\CustHub\Model\ChRoomMember;
use Carbon\Carbon;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use Mine\Abstracts\AbstractService;
use Mine\Annotation\Transaction;
use Mine\MineModel;
use function Hyperf\Collection\collect;
use function Hyperf\Collection\data_get;

class ChContactWhiteService extends AbstractService
{
    public $mapper;

    #[Inject]
    protected ChContactBwDeleteRecordMapper $bwDeleteRecordMapper;

    public function __construct(ChContactWhiteMapper $mapper)
    {
        $this->mapper = $mapper;
    }

    public function list(array $data): array
    {
        $pageSize = data_get($data, 'page_size', MineModel::PAGE_SIZE);

        $keyword = data_get($data, 'keyword');

        $list = Db::table('ch_contact_white as a')
            ->selectRaw('a.id,a.user_id,b.nickname,b.avatar,b.is_wechat,b.corp_id,c.corp_name')
            ->join('ch_contact as b', 'a.user_id', '=', 'b.user_id')
            ->join('ch_corp as c', 'b.corp_id', '=', 'c.id')
            ->where('a.main_uid', $data['main_uid'])
            ->when(!empty($data['add_start_time']) && !empty($data['add_end_time']), function ($query) use ($data) {
                $query->whereBetween('a.created_at', [$data['add_start_time'], $data['add_end_time']]);
            })
            ->when(!empty($keyword), function ($query) use ($keyword) {
                if (is_numeric($keyword)) {
                    $query->where('a.user_id', $keyword);
                } else {
                    $query->where('b.nickname', 'like', '%' . $keyword . '%');
                }
            })
            ->groupBy('user_id')
            ->orderBy('a.created_at', 'desc')
            ->paginate((int)$pageSize);

        return $this->mapper->setPaginate($list);
    }

    /**
     * 新增白名单
     * @param array $data
     * @return bool
     */
    #[Transaction]
    public function saveWhite(array $data): bool
    {
        $userIds = json_decode($data['user_ids'], true);

        $existingContactMap = ChContactWhite::query()
            ->whereIn('user_id', $userIds)
            ->pluck('id', 'user_id');

        $toInsertUserIds = collect($userIds)->reject(fn($item) => $existingContactMap->has($item))->toArray();

        $toInsert = [];
        foreach ($toInsertUserIds as $userId) {
            $toInsert[] = [
                'uid' => $data['uid'],
                'main_uid' => $data['main_uid'],
                'user_id' => $userId,
            ];
        }

        if (empty($toInsert)) {
            return true;
        }

        ChContact::query()
            ->whereIn('user_id', $toInsertUserIds)
            ->update(['is_white' => 1]);

        ChRoomMember::query()
            ->whereIn('user_id', $toInsertUserIds)
            ->update(['is_white' => 1]);

        return $this->batchSave($toInsert);
    }

    /**
     * 删除黑名单
     * @param array $data
     * @return bool
     * @throws \Exception
     */
    #[Transaction]
    public function deleteWhite(array $data): bool
    {
        $ids = json_decode($data['ids'], true);
        $this->del($data['main_uid'],$ids);
        return true;
    }

    /**
     * 清空黑名单
     * @param array $data
     * @return bool
     */
    #[Transaction]
    public function clear(array $data): bool
    {
        $this->del($data['main_uid']);
        return true;
    }


    private function del(mixed $mainUid, array $ids = []): bool
    {
        $list = $this->mapper->model::query()
            ->when(!empty($ids),function ($query) use ($ids){
                $query->whereIn('id', $ids);
            })
            ->where('main_uid', $mainUid)
            ->get();

        if($list->isEmpty()){
            return true;
        }

        $recordData = [];
        $userIds = [];
        foreach ($list as $info) {
            $userIds[] = $info->user_id;
            $recordData[] = [
                'uid' => $info->uid,
                'main_uid' => $info->main_uid,
                'user_id' => $info->user_id,
                'join_time' => $info->created_at,
                'type' => 1,
                'delete_time' => Carbon::now()->toDateTimeString()
            ];
        }
        //删除白名单
        $this->mapper->model::query()
            ->when(!empty($ids),function ($query) use ($ids){
                $query->whereIn('id', $ids);
            })
            ->where('main_uid', $mainUid)
            ->delete();

        //更新客户白名单状态
        ChContact::query()
            ->whereIn('user_id',$userIds)
            ->update([
                'is_white' => 0
            ]);

        ChRoomMember::query()
            ->whereIn('user_id', $userIds)
            ->update(['is_white' => 0]);

        //记录删除记录
        $this->bwDeleteRecordMapper->model::insert($recordData);
        return true;
    }
}